package com.fiona.core.load;


import java.util.List;
import java.util.Set;

import com.fiona.annotation.FionaApi;
import com.fiona.annotation.FionaBean;
import com.fiona.annotation.FionaDao;
import com.fiona.annotation.FionaInterceptor;
import com.fiona.annotation.FionaOnLoad;
import com.fiona.common.constant.FionaConstant;
import com.fiona.common.constant.FionaSpace;
import com.fiona.core.model.FionaBeanClassModel;

/**
 * 加载本地资源
 */
public class LoadBeans {

    private static FionaSpace constants = FionaSpace.getFionaSpace();

    /**
     * 加载所有的bean，包括FionaApi 的class对象
     *
     * @throws Exception 异常
     */
    public static void loadBeans() throws Exception {
        try {

            Set<String> scanClassList = LoadHelper.getSacnClassList();

            for (String str : scanClassList) {
                Class<?> cls = Class.forName(str);
                FionaApi fionaApi = cls.getAnnotation(FionaApi.class);
                FionaBean fionaBean = cls.getAnnotation(FionaBean.class);
                FionaInterceptor interceptor = cls.getAnnotation(FionaInterceptor.class);
                FionaDao dao = cls.getAnnotation(FionaDao.class);
                FionaOnLoad onLoad = cls.getAnnotation(FionaOnLoad.class);

                int count = 0;

                if(fionaApi != null) {
                    LoadBeans.loadFionaApi(cls, fionaApi);
                    count++;
                }
                if(fionaBean != null) {
                    LoadBeans.loadfionaBean(cls, fionaBean);
                    count++;
                }
                if(interceptor != null){
                    LoadBeans.loadInterceptor(cls, interceptor);
                    count++;
                }
                if(dao != null){
                    LoadBeans.loadDao(cls, dao);
                    count++;
                }
                if(onLoad != null){
                    LoadBeans.loadFionaAfter(cls);
                    count++;
                }

                if(count > 1){
                    throw new Exception("类:["+cls.getName()+"]上不允许有多个Fiona注解");
                }
            }
        } catch (Exception e) {
            throw new Exception("从扫描出来的类里面筛选有注解的类,出现异常",e);
        }
    }

    /**
     * 将所有FionaApi存到全局存储空间
     * @param cls 类型
     * @param fionaApi 注解
     */
    public static void loadFionaApi(Class<?> cls, FionaApi fionaApi) {

        List<FionaBeanClassModel> fionaApis = LoadHelper.getFionaApiList();

        FionaBeanClassModel fionaBeanClassModel = new FionaBeanClassModel();
        fionaBeanClassModel.setClassName(cls);
        fionaBeanClassModel.setAnnotation(fionaApi);

        fionaApis.add(fionaBeanClassModel);
        constants.setAttr(FionaConstant.FIONA_API, fionaApis);
    }

    /**
     * 将所有fionaBean存到全局存储空间
     * @param cls 类型
     * @param fionaBean 注解
     */
    public static void loadfionaBean(Class<?> cls, FionaBean fionaBean) {

        List<FionaBeanClassModel> fionaBeans = LoadHelper.getBeanList();

        FionaBeanClassModel fionaBeanClassModel = new FionaBeanClassModel();
        fionaBeanClassModel.setClassName(cls);
        fionaBeanClassModel.setAnnotation(fionaBean);

        fionaBeans.add(fionaBeanClassModel);
        constants.setAttr(FionaConstant.FIONA_BEANS, fionaBeans);
    }

    /**
     * 将所有拦截器存到全局存储空间
     * @param cls 类型
     * @param interceptor 注解
     */
    public static void loadInterceptor(Class<?> cls, FionaInterceptor interceptor){

        List<FionaBeanClassModel> interceptors = LoadHelper.getInterceptorList();

        FionaBeanClassModel fionaBeanClassModel = new FionaBeanClassModel();
        fionaBeanClassModel.setClassName(cls);
        fionaBeanClassModel.setAnnotation(interceptor);

        interceptors.add(fionaBeanClassModel);
        constants.setAttr(FionaConstant.INTERCEPTORS, interceptors);
    }

    /**
     * 加载dao
     * @param cls 类型
     * @param fionaDao 注解
     */
    public static void loadDao(Class<?> cls, FionaDao fionaDao){

        List<FionaBeanClassModel> fionaDaos = LoadHelper.getDaoList();

        FionaBeanClassModel fionaBeanClassModel = new FionaBeanClassModel();
        fionaBeanClassModel.setClassName(cls);
        fionaBeanClassModel.setAnnotation(fionaDao);

        fionaDaos.add(fionaBeanClassModel);
        constants.setAttr(FionaConstant.FIONA_DAOS, fionaDaos);
    }

    /**
     * 加载fionaAfter
     * @param cls 类型
     */
    public static void loadFionaAfter(Class<?> cls){
        List<Class> fionaAfters = LoadHelper.getFionaAfterList();
        fionaAfters.add(cls);
        constants.setAttr(FionaConstant.FIONA_AFTERS, fionaAfters);
    }
}
